package xworker.javafxcontrol.control;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import xworker.javafx.util.JavaFXUtils;
import xworker.lang.executor.Executor;
import xworker.lang.util.XWorkerUtils;

import java.util.HashMap;
import java.util.Map;

public class ThingMenu implements EventHandler<ActionEvent> {
    private static final String TAG = ThingMenu.class.getName();
    Thing thing;
    ActionContext actionContext;
    Map<String, MenuItem> menuItemMap = new HashMap<>();

    public ThingMenu(Thing thing, ActionContext actionContext){
        this.thing = thing;
        this.actionContext = actionContext;

        Object parent = actionContext.getObject("parent");
        Thing thingForMenu = thing.doAction("getThing", actionContext);
        boolean hasRoot = thing.getBoolean("hasRoot");
        if(thingForMenu != null){
            if(hasRoot){
                create(parent, thingForMenu);
            }else{
                for(Thing child : thingForMenu.getChilds()){
                    create(parent, child);
                }
            }
        }else{
            Executor.warn(TAG, "Thing for menu is null, thingMenu=" + thing.getMetadata().getPath());
        }
    }

    public MenuItem getMenuItem(String name){
        return menuItemMap.get(name);
    }

    public Map<String, MenuItem> getMenuItemMap() {
        return menuItemMap;
    }

    public Thing getThing() {
        return thing;
    }

    public ActionContext getActionContext() {
        return actionContext;
    }

    private void create(Object parent, Thing thing){
        String icon = XWorkerUtils.getThingIcon(thing);
        Image image = JavaFXUtils.getImage(icon);

        if(thing.getChilds().size() == 0){
            MenuItem menuItem = new MenuItem();
            menuItem.setText(thing.getMetadata().getLabel());
            menuItem.getProperties().put("thing", thing);
            menuItem.setOnAction(this);
            if(image != null){
                menuItem.setGraphic(new ImageView(image));
            }

            if(parent instanceof Menu){
                ((Menu) parent).getItems().add(menuItem);
            }else if(parent instanceof ContextMenu){
                ((ContextMenu) parent).getItems().add(menuItem);
            }else if(parent instanceof Control){
                ContextMenu contextMenu = new ContextMenu();
                contextMenu.getItems().add(menuItem);
                ((Control) parent).setContextMenu(contextMenu);
            }

            menuItemMap.put(thing.getMetadata().getName(), menuItem);
            menuItemMap.put(thing.getMetadata().getPath(), menuItem);
        }else{
            Menu menu = new Menu();
            menu.setOnAction(this);
            menu.setText(thing.getMetadata().getLabel());
            menu.getProperties().put("thing", thing);
            if(image != null){
                menu.setGraphic(new ImageView(image));
            }

            if(parent instanceof MenuBar){
                ((MenuBar) parent).getMenus().add(menu);
            }else if(parent instanceof Menu){
                ((Menu) parent).getItems().add(menu);
            }else if(parent instanceof ContextMenu){
                ((ContextMenu) parent).getItems().add(menu);
            }else if(parent instanceof Control){
                ContextMenu contextMenu = new ContextMenu();
                contextMenu.getItems().add(menu);
                ((Control) parent).setContextMenu(contextMenu);
            }

            menuItemMap.put(thing.getMetadata().getName(), menu);
            menuItemMap.put(thing.getMetadata().getPath(), menu);

            for(Thing child : thing.getChilds()){
                create(menu, child);
            }
        }
    }

    @Override
    public void handle(ActionEvent event) {
        MenuItem menuItem = (MenuItem) event.getSource();
        Thing menuThing = (Thing) menuItem.getProperties().get("thing");

        if(thing.getBoolean("executeItemAction")) {
            if (menuThing != null) {
                menuThing.doAction("doAction", actionContext, "event", event, "thingMenu", this, "thing", menuThing);
            }
        }

        thing.doAction("doAction", actionContext, "event", event, "thingMenu", this, "thing", menuThing);
    }

    public static void create(ActionContext actionContext){
        Thing self = actionContext.getObject("self");
        ThingMenu thingMenu = new ThingMenu(self, actionContext);
        actionContext.g().put(self.getMetadata().getName(), thingMenu);
    }

}
